package com.itheima.appserver.service;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.jwt.JWTPayload;
import cn.hutool.jwt.JWTUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.itheima.appserver.excepiton.MyException;
import com.itheima.appserver.interceptor.UserThreadLocal;
import com.itheima.commons.constants.Constants;
import com.itheima.commons.model.domain.Admin;
import com.itheima.commons.model.domain.AdminLogin;
import com.itheima.commons.model.domain.UserInfo;
import com.itheima.commons.model.vo.AdminVo;
import com.itheima.commons.model.vo.ErrorResult;
import com.itheima.dubbo.interfaces.AdminApi;
import com.itheima.dubbo.interfaces.SystemApi;
import com.itheima.dubbo.interfaces.UserInfoApi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 系统登录功能
 */
@Service
public class SystemService {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Reference
    private SystemApi systemApi;
    @Reference
    private UserInfoApi userInfoApi;
    @Reference
    private AdminApi adminApi;

    /**
     * 用户登录校验
     * 账号 15800807988
     * 密码123456
     *
     * @param params 账号，密码，验证码，同获取验证码时uuid
     * @return
     */
    public Map checkUserLogin(Map<String, String> params, HttpServletResponse response) {

        HashMap<String, String> hashMap = new HashMap<>();
        String username = params.get("username");
        String password = params.get("password");
        //用户传过来验证码
        String token = params.get("verificationCode");
        //验证码的标记
        String uuid = params.get("uuid");

        //判断账号或密码是否为空 Account or password cannot be empty
        if (ObjectUtil.hasEmpty(username) || ObjectUtil.hasEmpty(password)) {
            // 抛自定义异常
            throw new MyException(ErrorResult.usernameOrPasswordIsNull());
        }
        //验证码为空，提示：请输入验证码
        if (ObjectUtil.hasEmpty(token)) {
            // 抛自定义异常
            throw new MyException(ErrorResult.userCodeIsNull());
        }

        //根据用户的用户名查询数据库判断是否正确
        AdminLogin admin = systemApi.queryWithNameAndPsw(username, password);
        if (ObjectUtil.hasEmpty(admin)) {
            //adminVerificationCode(uuid,response);
            throw new MyException(ErrorResult.adminLoginError());
        }
        //判断验证码是否一致
        String code = redisTemplate.opsForValue().get(Constants.SMS_CODE + uuid);
        if (!code.equals(token)) {
            throw new MyException(ErrorResult.verificationCodeCheckError());
        }

        //删除验证码
        redisTemplate.delete(Constants.SMS_CODE + uuid);

        // 生成管理员Token
        Map<String, Object> map = new HashMap<>();
        map.put("uid", admin.getId());
        map.put(JWTPayload.EXPIRES_AT, DateTime.of(System.currentTimeMillis() + Constants.JWT_TIME_OUT));
        String adminToken = JWTUtil.createToken(map, Constants.JWT_SECRET.getBytes());
        hashMap.put("token", adminToken);

        return hashMap;
    }

    //返回验证码图片
    public void adminVerificationCode(String uuid, HttpServletResponse response) {
        //判断之前的验证码是否存在，如果存在删除验证码（重新生成新的验证码）
        String s = redisTemplate.opsForValue().get(Constants.SMS_CODE + uuid);
        if (!ObjectUtil.hasEmpty(s)) {
            redisTemplate.delete(Constants.SMS_CODE + uuid);
        }
        //定义图形验证码的长和宽
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100);
        //获取随机生成的验证码
        String code = lineCaptcha.getCode();
        System.out.println(code);
        ServletOutputStream outputStream = null;
        try {
            //将验证码存储进redis中
            redisTemplate.opsForValue().set(Constants.SMS_CODE + uuid, code, 5, TimeUnit.MINUTES);
            //返回图片流给前端
            outputStream = response.getOutputStream();
            lineCaptcha.write(outputStream);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关流
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    //用户基本信息
    public AdminVo adminProfile() {
        AdminVo adminVo = new AdminVo();
        long userId = UserThreadLocal.getUserId();
        //判断管理员登录是否成功
        if (ObjectUtil.isEmpty(userId)) {
            return adminVo;
        }
        Admin admin = adminApi.queryWithId(userId);
        adminVo.setUid(admin.getAdminId().toString());
        adminVo.setAvatar(admin.getAvatar());
        adminVo.setUsername(admin.getUsername());
        return adminVo;
    }

}
